// 版权归 Epic Games, Inc. 所有，保留所有权利。

#include "LyraPerfStatContainerBase.h"

#include "Blueprint/WidgetTree.h"
#include "LyraPerfStatWidgetBase.h"
#include "Settings/LyraSettingsLocal.h"

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraPerfStatContainerBase)

//////////////////////////////////////////////////////////////////////
// ULyraPerfStatsContainerBase

ULyraPerfStatContainerBase::ULyraPerfStatContainerBase(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer) // 调用父类构造函数
{
}

/**
 * 原生构造函数，在控件创建时调用。
 * 注册用户设置更改的回调并更新子控件可见性。
 */
void ULyraPerfStatContainerBase::NativeConstruct()
{
	Super::NativeConstruct(); // 调用父类的 NativeConstruct
	UpdateVisibilityOfChildren(); // 更新子控件可见性

	ULyraSettingsLocal::Get()->OnPerfStatDisplayStateChanged().AddUObject(this, &ThisClass::UpdateVisibilityOfChildren); // 注册性能统计显示状态更改的回调
}

/**
 * 原生析构函数，在控件销毁时调用。
 * 移除用户设置更改的回调。
 */
void ULyraPerfStatContainerBase::NativeDestruct()
{
	ULyraSettingsLocal::Get()->OnPerfStatDisplayStateChanged().RemoveAll(this); // 移除所有注册的回调

	Super::NativeDestruct(); // 调用父类的 NativeDestruct
}

/**
 * 更新所有子控件的可见性。
 * 根据用户设置和当前显示模式过滤器（文本/图表）来显示或隐藏子控件。
 */
void ULyraPerfStatContainerBase::UpdateVisibilityOfChildren()
{
	ULyraSettingsLocal* UserSettings = ULyraSettingsLocal::Get(); // 获取本地用户设置

	const bool bShowTextWidgets = (StatDisplayModeFilter == ELyraStatDisplayMode::TextOnly) || (StatDisplayModeFilter == ELyraStatDisplayMode::TextAndGraph); // 是否显示文本控件
	const bool bShowGraphWidgets = (StatDisplayModeFilter == ELyraStatDisplayMode::GraphOnly) || (StatDisplayModeFilter == ELyraStatDisplayMode::TextAndGraph); // 是否显示图表控件
	
	check(WidgetTree); // 确保 WidgetTree 有效
	WidgetTree->ForEachWidget([&](UWidget* Widget) // 遍历所有子控件
	{
		if (ULyraPerfStatWidgetBase* TypedWidget = Cast<ULyraPerfStatWidgetBase>(Widget)) // 如果控件是 ULyraPerfStatWidgetBase 类型
		{
			const ELyraStatDisplayMode SettingMode = UserSettings->GetPerfStatDisplayState(TypedWidget->GetStatToDisplay()); // 获取该统计的显示模式

			bool bShowWidget = false; // 是否显示该控件
			switch (SettingMode) // 根据显示模式决定
			{
			case ELyraStatDisplayMode::Hidden: // 隐藏模式
				bShowWidget = false; // 不显示
				break;
			case ELyraStatDisplayMode::TextOnly: // 仅文本模式
				bShowWidget = bShowTextWidgets; // 如果当前过滤器允许文本则显示
				break;
			case ELyraStatDisplayMode::GraphOnly: // 仅图表模式
				bShowWidget = bShowGraphWidgets; // 如果当前过滤器允许图表则显示
				break;
			case ELyraStatDisplayMode::TextAndGraph: // 文本和图表模式
				bShowWidget = bShowTextWidgets || bShowGraphWidgets; // 如果当前过滤器允许文本或图表则显示
				break;
			}

			TypedWidget->SetVisibility(bShowWidget ? ESlateVisibility::HitTestInvisible : ESlateVisibility::Collapsed); // 设置控件可见性
		}
	});
}